home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / urllib.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  41KB  |  1,627 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import string
  5. import socket
  6. import os
  7. import time
  8. import sys
  9. from urlparse import urljoin as basejoin
  10. __all__ = [
  11.     'urlopen',
  12.     'URLopener',
  13.     'FancyURLopener',
  14.     'urlretrieve',
  15.     'urlcleanup',
  16.     'quote',
  17.     'quote_plus',
  18.     'unquote',
  19.     'unquote_plus',
  20.     'urlencode',
  21.     'url2pathname',
  22.     'pathname2url',
  23.     'splittag',
  24.     'localhost',
  25.     'thishost',
  26.     'ftperrors',
  27.     'basejoin',
  28.     'unwrap',
  29.     'splittype',
  30.     'splithost',
  31.     'splituser',
  32.     'splitpasswd',
  33.     'splitport',
  34.     'splitnport',
  35.     'splitquery',
  36.     'splitattr',
  37.     'splitvalue',
  38.     'splitgophertype',
  39.     'getproxies']
  40. __version__ = '1.17'
  41. MAXFTPCACHE = 10
  42. if os.name == 'mac':
  43.     from macurl2path import url2pathname, pathname2url
  44. elif os.name == 'nt':
  45.     from nturl2path import url2pathname, pathname2url
  46. elif os.name == 'riscos':
  47.     from rourl2path import url2pathname, pathname2url
  48. else:
  49.     
  50.     def url2pathname(pathname):
  51.         return unquote(pathname)
  52.  
  53.     
  54.     def pathname2url(pathname):
  55.         return quote(pathname)
  56.  
  57. _urlopener = None
  58.  
  59. def urlopen(url, data = None, proxies = None):
  60.     global _urlopener
  61.     if proxies is not None:
  62.         opener = FancyURLopener(proxies = proxies)
  63.     elif not _urlopener:
  64.         opener = FancyURLopener()
  65.         _urlopener = opener
  66.     else:
  67.         opener = _urlopener
  68.     if data is None:
  69.         return opener.open(url)
  70.     else:
  71.         return opener.open(url, data)
  72.  
  73.  
  74. def urlretrieve(url, filename = None, reporthook = None, data = None):
  75.     global _urlopener
  76.     if not _urlopener:
  77.         _urlopener = FancyURLopener()
  78.     
  79.     return _urlopener.retrieve(url, filename, reporthook, data)
  80.  
  81.  
  82. def urlcleanup():
  83.     if _urlopener:
  84.         _urlopener.cleanup()
  85.     
  86.  
  87.  
  88. class ContentTooShortError(IOError):
  89.     
  90.     def __init__(self, message, content):
  91.         IOError.__init__(self, message)
  92.         self.content = content
  93.  
  94.  
  95. ftpcache = { }
  96.  
  97. class URLopener:
  98.     __tempfiles = None
  99.     version = 'Python-urllib/%s' % __version__
  100.     
  101.     def __init__(self, proxies = None, **x509):
  102.         if proxies is None:
  103.             proxies = getproxies()
  104.         
  105.         self.proxies = proxies
  106.         self.key_file = x509.get('key_file')
  107.         self.cert_file = x509.get('cert_file')
  108.         self.addheaders = [
  109.             ('User-Agent', self.version)]
  110.         self._URLopener__tempfiles = []
  111.         self._URLopener__unlink = os.unlink
  112.         self.tempcache = None
  113.         self.ftpcache = ftpcache
  114.  
  115.     
  116.     def __del__(self):
  117.         self.close()
  118.  
  119.     
  120.     def close(self):
  121.         self.cleanup()
  122.  
  123.     
  124.     def cleanup(self):
  125.         if self._URLopener__tempfiles:
  126.             for file in self._URLopener__tempfiles:
  127.                 
  128.                 try:
  129.                     self._URLopener__unlink(file)
  130.                 continue
  131.                 except OSError:
  132.                     continue
  133.                 
  134.  
  135.             
  136.             del self._URLopener__tempfiles[:]
  137.         
  138.         if self.tempcache:
  139.             self.tempcache.clear()
  140.         
  141.  
  142.     
  143.     def addheader(self, *args):
  144.         self.addheaders.append(args)
  145.  
  146.     
  147.     def open(self, fullurl, data = None):
  148.         fullurl = unwrap(toBytes(fullurl))
  149.         if self.tempcache and fullurl in self.tempcache:
  150.             (filename, headers) = self.tempcache[fullurl]
  151.             fp = open(filename, 'rb')
  152.             return addinfourl(fp, headers, fullurl)
  153.         
  154.         (urltype, url) = splittype(fullurl)
  155.         if not urltype:
  156.             urltype = 'file'
  157.         
  158.         if urltype in self.proxies:
  159.             proxy = self.proxies[urltype]
  160.             (urltype, proxyhost) = splittype(proxy)
  161.             (host, selector) = splithost(proxyhost)
  162.             url = (host, fullurl)
  163.         else:
  164.             proxy = None
  165.         name = 'open_' + urltype
  166.         self.type = urltype
  167.         name = name.replace('-', '_')
  168.         if not hasattr(self, name):
  169.             if proxy:
  170.                 return self.open_unknown_proxy(proxy, fullurl, data)
  171.             else:
  172.                 return self.open_unknown(fullurl, data)
  173.         
  174.         
  175.         try:
  176.             if data is None:
  177.                 return getattr(self, name)(url)
  178.             else:
  179.                 return getattr(self, name)(url, data)
  180.         except socket.error:
  181.             msg = None
  182.             raise IOError, ('socket error', msg), sys.exc_info()[2]
  183.  
  184.  
  185.     
  186.     def open_unknown(self, fullurl, data = None):
  187.         (type, url) = splittype(fullurl)
  188.         raise IOError, ('url error', 'unknown url type', type)
  189.  
  190.     
  191.     def open_unknown_proxy(self, proxy, fullurl, data = None):
  192.         (type, url) = splittype(fullurl)
  193.         raise IOError, ('url error', 'invalid proxy for %s' % type, proxy)
  194.  
  195.     
  196.     def retrieve(self, url, filename = None, reporthook = None, data = None):
  197.         url = unwrap(toBytes(url))
  198.         if self.tempcache and url in self.tempcache:
  199.             return self.tempcache[url]
  200.         
  201.         (type, url1) = splittype(url)
  202.         if filename is None:
  203.             if not type or type == 'file':
  204.                 
  205.                 try:
  206.                     fp = self.open_local_file(url1)
  207.                     hdrs = fp.info()
  208.                     del fp
  209.                     return (url2pathname(splithost(url1)[1]), hdrs)
  210.                 except IOError:
  211.                     msg = None
  212.                 except:
  213.                     None<EXCEPTION MATCH>IOError
  214.                 
  215.  
  216.         None<EXCEPTION MATCH>IOError
  217.         fp = self.open(url, data)
  218.         headers = fp.info()
  219.         if filename:
  220.             tfp = open(filename, 'wb')
  221.         else:
  222.             import tempfile as tempfile
  223.             (garbage, path) = splittype(url)
  224.             if not path:
  225.                 pass
  226.             (garbage, path) = splithost('')
  227.             if not path:
  228.                 pass
  229.             (path, garbage) = splitquery('')
  230.             if not path:
  231.                 pass
  232.             (path, garbage) = splitattr('')
  233.             suffix = os.path.splitext(path)[1]
  234.             (fd, filename) = tempfile.mkstemp(suffix)
  235.             self._URLopener__tempfiles.append(filename)
  236.             tfp = os.fdopen(fd, 'wb')
  237.         result = (filename, headers)
  238.         if self.tempcache is not None:
  239.             self.tempcache[url] = result
  240.         
  241.         bs = 8192
  242.         size = -1
  243.         read = 0
  244.         blocknum = 0
  245.         if reporthook:
  246.             if 'content-length' in headers:
  247.                 size = int(headers['Content-Length'])
  248.             
  249.             reporthook(blocknum, bs, size)
  250.         
  251.         while None:
  252.             block = fp.read(bs)
  253.             if block == '':
  254.                 break
  255.             
  256.             read += len(block)
  257.             blocknum += 1
  258.             if reporthook:
  259.                 reporthook(blocknum, bs, size)
  260.                 continue
  261.             continue
  262.             fp.close()
  263.             tfp.close()
  264.             del fp
  265.             del tfp
  266.             if size >= 0 and read < size:
  267.                 raise ContentTooShortError('retrieval incomplete: got only %i out of %i bytes' % (read, size), result)
  268.             
  269.         return result
  270.  
  271.     
  272.     def open_http(self, url, data = None):
  273.         import httplib as httplib
  274.         user_passwd = None
  275.         proxy_passwd = None
  276.         if isinstance(url, str):
  277.             (host, selector) = splithost(url)
  278.             if host:
  279.                 (user_passwd, host) = splituser(host)
  280.                 host = unquote(host)
  281.             
  282.             realhost = host
  283.         else:
  284.             (host, selector) = url
  285.             (proxy_passwd, host) = splituser(host)
  286.             (urltype, rest) = splittype(selector)
  287.             url = rest
  288.             user_passwd = None
  289.             if urltype.lower() != 'http':
  290.                 realhost = None
  291.             else:
  292.                 (realhost, rest) = splithost(rest)
  293.                 if realhost:
  294.                     (user_passwd, realhost) = splituser(realhost)
  295.                 
  296.                 if user_passwd:
  297.                     selector = '%s://%s%s' % (urltype, realhost, rest)
  298.                 
  299.                 if proxy_bypass(realhost):
  300.                     host = realhost
  301.                 
  302.         if not host:
  303.             raise IOError, ('http error', 'no host given')
  304.         
  305.         if proxy_passwd:
  306.             import base64 as base64
  307.             proxy_auth = base64.b64encode(proxy_passwd).strip()
  308.         else:
  309.             proxy_auth = None
  310.         if user_passwd:
  311.             import base64 as base64
  312.             auth = base64.b64encode(user_passwd).strip()
  313.         else:
  314.             auth = None
  315.         h = httplib.HTTP(host)
  316.         if data is not None:
  317.             h.putrequest('POST', selector)
  318.             h.putheader('Content-Type', 'application/x-www-form-urlencoded')
  319.             h.putheader('Content-Length', '%d' % len(data))
  320.         else:
  321.             h.putrequest('GET', selector)
  322.         if proxy_auth:
  323.             h.putheader('Proxy-Authorization', 'Basic %s' % proxy_auth)
  324.         
  325.         if auth:
  326.             h.putheader('Authorization', 'Basic %s' % auth)
  327.         
  328.         if realhost:
  329.             h.putheader('Host', realhost)
  330.         
  331.         for args in self.addheaders:
  332.             h.putheader(*args)
  333.         
  334.         h.endheaders()
  335.         if data is not None:
  336.             h.send(data)
  337.         
  338.         (errcode, errmsg, headers) = h.getreply()
  339.         if errcode == -1:
  340.             raise IOError, ('http protocol error', 0, 'got a bad status line', None)
  341.         
  342.         fp = h.getfile()
  343.         if errcode == 200:
  344.             return addinfourl(fp, headers, 'http:' + url)
  345.         elif data is None:
  346.             return self.http_error(url, fp, errcode, errmsg, headers)
  347.         else:
  348.             return self.http_error(url, fp, errcode, errmsg, headers, data)
  349.  
  350.     
  351.     def http_error(self, url, fp, errcode, errmsg, headers, data = None):
  352.         name = 'http_error_%d' % errcode
  353.         if hasattr(self, name):
  354.             method = getattr(self, name)
  355.             if data is None:
  356.                 result = method(url, fp, errcode, errmsg, headers)
  357.             else:
  358.                 result = method(url, fp, errcode, errmsg, headers, data)
  359.             if result:
  360.                 return result
  361.             
  362.         
  363.         return self.http_error_default(url, fp, errcode, errmsg, headers)
  364.  
  365.     
  366.     def http_error_default(self, url, fp, errcode, errmsg, headers):
  367.         void = fp.read()
  368.         fp.close()
  369.         raise IOError, ('http error', errcode, errmsg, headers)
  370.  
  371.     if hasattr(socket, 'ssl'):
  372.         
  373.         def open_https(self, url, data = None):
  374.             import httplib
  375.             user_passwd = None
  376.             proxy_passwd = None
  377.             if isinstance(url, str):
  378.                 (host, selector) = splithost(url)
  379.                 if host:
  380.                     (user_passwd, host) = splituser(host)
  381.                     host = unquote(host)
  382.                 
  383.                 realhost = host
  384.             else:
  385.                 (host, selector) = url
  386.                 (proxy_passwd, host) = splituser(host)
  387.                 (urltype, rest) = splittype(selector)
  388.                 url = rest
  389.                 user_passwd = None
  390.                 if urltype.lower() != 'https':
  391.                     realhost = None
  392.                 else:
  393.                     (realhost, rest) = splithost(rest)
  394.                     if realhost:
  395.                         (user_passwd, realhost) = splituser(realhost)
  396.                     
  397.                     if user_passwd:
  398.                         selector = '%s://%s%s' % (urltype, realhost, rest)
  399.                     
  400.             if not host:
  401.                 raise IOError, ('https error', 'no host given')
  402.             
  403.             if proxy_passwd:
  404.                 import base64
  405.                 proxy_auth = base64.b64encode(proxy_passwd).strip()
  406.             else:
  407.                 proxy_auth = None
  408.             if user_passwd:
  409.                 import base64
  410.                 auth = base64.b64encode(user_passwd).strip()
  411.             else:
  412.                 auth = None
  413.             h = httplib.HTTPS(host, 0, key_file = self.key_file, cert_file = self.cert_file)
  414.             if data is not None:
  415.                 h.putrequest('POST', selector)
  416.                 h.putheader('Content-Type', 'application/x-www-form-urlencoded')
  417.                 h.putheader('Content-Length', '%d' % len(data))
  418.             else:
  419.                 h.putrequest('GET', selector)
  420.             if proxy_auth:
  421.                 h.putheader('Proxy-Authorization', 'Basic %s' % proxy_auth)
  422.             
  423.             if auth:
  424.                 h.putheader('Authorization', 'Basic %s' % auth)
  425.             
  426.             if realhost:
  427.                 h.putheader('Host', realhost)
  428.             
  429.             for args in self.addheaders:
  430.                 h.putheader(*args)
  431.             
  432.             h.endheaders()
  433.             if data is not None:
  434.                 h.send(data)
  435.             
  436.             (errcode, errmsg, headers) = h.getreply()
  437.             if errcode == -1:
  438.                 raise IOError, ('http protocol error', 0, 'got a bad status line', None)
  439.             
  440.             fp = h.getfile()
  441.             if errcode == 200:
  442.                 return addinfourl(fp, headers, 'https:' + url)
  443.             elif data is None:
  444.                 return self.http_error(url, fp, errcode, errmsg, headers)
  445.             else:
  446.                 return self.http_error(url, fp, errcode, errmsg, headers, data)
  447.  
  448.     
  449.     
  450.     def open_gopher(self, url):
  451.         if not isinstance(url, str):
  452.             raise IOError, ('gopher error', 'proxy support for gopher protocol currently not implemented')
  453.         
  454.         import gopherlib as gopherlib
  455.         (host, selector) = splithost(url)
  456.         if not host:
  457.             raise IOError, ('gopher error', 'no host given')
  458.         
  459.         host = unquote(host)
  460.         (type, selector) = splitgophertype(selector)
  461.         (selector, query) = splitquery(selector)
  462.         selector = unquote(selector)
  463.         if query:
  464.             query = unquote(query)
  465.             fp = gopherlib.send_query(selector, query, host)
  466.         else:
  467.             fp = gopherlib.send_selector(selector, host)
  468.         return addinfourl(fp, noheaders(), 'gopher:' + url)
  469.  
  470.     
  471.     def open_file(self, url):
  472.         if not isinstance(url, str):
  473.             raise IOError, ('file error', 'proxy support for file protocol currently not implemented')
  474.         
  475.         if url[:2] == '//' and url[2:3] != '/' and url[2:12].lower() != 'localhost/':
  476.             return self.open_ftp(url)
  477.         else:
  478.             return self.open_local_file(url)
  479.  
  480.     
  481.     def open_local_file(self, url):
  482.         import mimetypes as mimetypes
  483.         import mimetools as mimetools
  484.         import email.Utils as email
  485.         
  486.         try:
  487.             StringIO = StringIO
  488.             import cStringIO
  489.         except ImportError:
  490.             StringIO = StringIO
  491.             import StringIO
  492.  
  493.         (host, file) = splithost(url)
  494.         localname = url2pathname(file)
  495.         
  496.         try:
  497.             stats = os.stat(localname)
  498.         except OSError:
  499.             e = None
  500.             raise IOError(e.errno, e.strerror, e.filename)
  501.  
  502.         size = stats.st_size
  503.         modified = email.Utils.formatdate(stats.st_mtime, usegmt = True)
  504.         mtype = mimetypes.guess_type(url)[0]
  505.         if not mtype:
  506.             pass
  507.         headers = mimetools.Message(StringIO('Content-Type: %s\nContent-Length: %d\nLast-modified: %s\n' % ('text/plain', size, modified)))
  508.         if not host:
  509.             urlfile = file
  510.             if file[:1] == '/':
  511.                 urlfile = 'file://' + file
  512.             
  513.             return addinfourl(open(localname, 'rb'), headers, urlfile)
  514.         
  515.         (host, port) = splitport(host)
  516.         if not port and socket.gethostbyname(host) in (localhost(), thishost()):
  517.             urlfile = file
  518.             if file[:1] == '/':
  519.                 urlfile = 'file://' + file
  520.             
  521.             return addinfourl(open(localname, 'rb'), headers, urlfile)
  522.         
  523.         raise IOError, ('local file error', 'not on local host')
  524.  
  525.     
  526.     def open_ftp(self, url):
  527.         if not isinstance(url, str):
  528.             raise IOError, ('ftp error', 'proxy support for ftp protocol currently not implemented')
  529.         
  530.         import mimetypes
  531.         import mimetools
  532.         
  533.         try:
  534.             StringIO = StringIO
  535.             import cStringIO
  536.         except ImportError:
  537.             StringIO = StringIO
  538.             import StringIO
  539.  
  540.         (host, path) = splithost(url)
  541.         if not host:
  542.             raise IOError, ('ftp error', 'no host given')
  543.         
  544.         (host, port) = splitport(host)
  545.         (user, host) = splituser(host)
  546.         if user:
  547.             (user, passwd) = splitpasswd(user)
  548.         else:
  549.             passwd = None
  550.         host = unquote(host)
  551.         if not user:
  552.             pass
  553.         user = unquote('')
  554.         if not passwd:
  555.             pass
  556.         passwd = unquote('')
  557.         host = socket.gethostbyname(host)
  558.         if not port:
  559.             import ftplib as ftplib
  560.             port = ftplib.FTP_PORT
  561.         else:
  562.             port = int(port)
  563.         (path, attrs) = splitattr(path)
  564.         path = unquote(path)
  565.         dirs = path.split('/')
  566.         dirs = dirs[:-1]
  567.         file = dirs[-1]
  568.         if dirs and not dirs[0]:
  569.             dirs = dirs[1:]
  570.         
  571.         if dirs and not dirs[0]:
  572.             dirs[0] = '/'
  573.         
  574.         key = (user, host, port, '/'.join(dirs))
  575.         if len(self.ftpcache) > MAXFTPCACHE:
  576.             for k in self.ftpcache.keys():
  577.                 if k != key:
  578.                     v = self.ftpcache[k]
  579.                     del self.ftpcache[k]
  580.                     v.close()
  581.                     continue
  582.             
  583.         
  584.         
  585.         try:
  586.             if key not in self.ftpcache:
  587.                 self.ftpcache[key] = ftpwrapper(user, passwd, host, port, dirs)
  588.             
  589.             if not file:
  590.                 type = 'D'
  591.             else:
  592.                 type = 'I'
  593.             for attr in attrs:
  594.                 (attr, value) = splitvalue(attr)
  595.                 if attr.lower() == 'type' and value in ('a', 'A', 'i', 'I', 'd', 'D'):
  596.                     type = value.upper()
  597.                     continue
  598.             
  599.             (fp, retrlen) = self.ftpcache[key].retrfile(file, type)
  600.             mtype = mimetypes.guess_type('ftp:' + url)[0]
  601.             headers = ''
  602.             if mtype:
  603.                 headers += 'Content-Type: %s\n' % mtype
  604.             
  605.             if retrlen is not None and retrlen >= 0:
  606.                 headers += 'Content-Length: %d\n' % retrlen
  607.             
  608.             headers = mimetools.Message(StringIO(headers))
  609.             return addinfourl(fp, headers, 'ftp:' + url)
  610.         except ftperrors():
  611.             msg = None
  612.             raise IOError, ('ftp error', msg), sys.exc_info()[2]
  613.  
  614.  
  615.     
  616.     def open_data(self, url, data = None):
  617.         if not isinstance(url, str):
  618.             raise IOError, ('data error', 'proxy support for data protocol currently not implemented')
  619.         
  620.         import mimetools
  621.         
  622.         try:
  623.             StringIO = StringIO
  624.             import cStringIO
  625.         except ImportError:
  626.             StringIO = StringIO
  627.             import StringIO
  628.  
  629.         
  630.         try:
  631.             (type, data) = url.split(',', 1)
  632.         except ValueError:
  633.             raise IOError, ('data error', 'bad data URL')
  634.  
  635.         if not type:
  636.             type = 'text/plain;charset=US-ASCII'
  637.         
  638.         semi = type.rfind(';')
  639.         if semi >= 0 and '=' not in type[semi:]:
  640.             encoding = type[semi + 1:]
  641.             type = type[:semi]
  642.         else:
  643.             encoding = ''
  644.         msg = []
  645.         msg.append('Date: %s' % time.strftime('%a, %d %b %Y %T GMT', time.gmtime(time.time())))
  646.         msg.append('Content-type: %s' % type)
  647.         if encoding == 'base64':
  648.             import base64
  649.             data = base64.decodestring(data)
  650.         else:
  651.             data = unquote(data)
  652.         msg.append('Content-Length: %d' % len(data))
  653.         msg.append('')
  654.         msg.append(data)
  655.         msg = '\n'.join(msg)
  656.         f = StringIO(msg)
  657.         headers = mimetools.Message(f, 0)
  658.         return addinfourl(f, headers, url)
  659.  
  660.  
  661.  
  662. class FancyURLopener(URLopener):
  663.     
  664.     def __init__(self, *args, **kwargs):
  665.         URLopener.__init__(self, *args, **kwargs)
  666.         self.auth_cache = { }
  667.         self.tries = 0
  668.         self.maxtries = 10
  669.  
  670.     
  671.     def http_error_default(self, url, fp, errcode, errmsg, headers):
  672.         return addinfourl(fp, headers, 'http:' + url)
  673.  
  674.     
  675.     def http_error_302(self, url, fp, errcode, errmsg, headers, data = None):
  676.         self.tries += 1
  677.         result = self.redirect_internal(url, fp, errcode, errmsg, headers, data)
  678.         self.tries = 0
  679.         return result
  680.  
  681.     
  682.     def redirect_internal(self, url, fp, errcode, errmsg, headers, data):
  683.         if 'location' in headers:
  684.             newurl = headers['location']
  685.         elif 'uri' in headers:
  686.             newurl = headers['uri']
  687.         else:
  688.             return None
  689.         void = fp.read()
  690.         fp.close()
  691.         newurl = basejoin(self.type + ':' + url, newurl)
  692.         return self.open(newurl)
  693.  
  694.     
  695.     def http_error_301(self, url, fp, errcode, errmsg, headers, data = None):
  696.         return self.http_error_302(url, fp, errcode, errmsg, headers, data)
  697.  
  698.     
  699.     def http_error_303(self, url, fp, errcode, errmsg, headers, data = None):
  700.         return self.http_error_302(url, fp, errcode, errmsg, headers, data)
  701.  
  702.     
  703.     def http_error_307(self, url, fp, errcode, errmsg, headers, data = None):
  704.         if data is None:
  705.             return self.http_error_302(url, fp, errcode, errmsg, headers, data)
  706.         else:
  707.             return self.http_error_default(url, fp, errcode, errmsg, headers)
  708.  
  709.     
  710.     def http_error_401(self, url, fp, errcode, errmsg, headers, data = None):
  711.         if 'www-authenticate' not in headers:
  712.             URLopener.http_error_default(self, url, fp, errcode, errmsg, headers)
  713.         
  714.         stuff = headers['www-authenticate']
  715.         import re as re
  716.         match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
  717.         if not match:
  718.             URLopener.http_error_default(self, url, fp, errcode, errmsg, headers)
  719.         
  720.         (scheme, realm) = match.groups()
  721.         if scheme.lower() != 'basic':
  722.             URLopener.http_error_default(self, url, fp, errcode, errmsg, headers)
  723.         
  724.         name = 'retry_' + self.type + '_basic_auth'
  725.         if data is None:
  726.             return getattr(self, name)(url, realm)
  727.         else:
  728.             return getattr(self, name)(url, realm, data)
  729.  
  730.     
  731.     def http_error_407(self, url, fp, errcode, errmsg, headers, data = None):
  732.         if 'proxy-authenticate' not in headers:
  733.             URLopener.http_error_default(self, url, fp, errcode, errmsg, headers)
  734.         
  735.         stuff = headers['proxy-authenticate']
  736.         import re
  737.         match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
  738.         if not match:
  739.             URLopener.http_error_default(self, url, fp, errcode, errmsg, headers)
  740.         
  741.         (scheme, realm) = match.groups()
  742.         if scheme.lower() != 'basic':
  743.             URLopener.http_error_default(self, url, fp, errcode, errmsg, headers)
  744.         
  745.         name = 'retry_proxy_' + self.type + '_basic_auth'
  746.         if data is None:
  747.             return getattr(self, name)(url, realm)
  748.         else:
  749.             return getattr(self, name)(url, realm, data)
  750.  
  751.     
  752.     def retry_proxy_http_basic_auth(self, url, realm, data = None):
  753.         (host, selector) = splithost(url)
  754.         newurl = 'http://' + host + selector
  755.         proxy = self.proxies['http']
  756.         (urltype, proxyhost) = splittype(proxy)
  757.         (proxyhost, proxyselector) = splithost(proxyhost)
  758.         i = proxyhost.find('@') + 1
  759.         proxyhost = proxyhost[i:]
  760.         (user, passwd) = self.get_user_passwd(proxyhost, realm, i)
  761.         if not user or passwd:
  762.             return None
  763.         
  764.         proxyhost = quote(user, safe = '') + ':' + quote(passwd, safe = '') + '@' + proxyhost
  765.         self.proxies['http'] = 'http://' + proxyhost + proxyselector
  766.         if data is None:
  767.             return self.open(newurl)
  768.         else:
  769.             return self.open(newurl, data)
  770.  
  771.     
  772.     def retry_proxy_https_basic_auth(self, url, realm, data = None):
  773.         (host, selector) = splithost(url)
  774.         newurl = 'https://' + host + selector
  775.         proxy = self.proxies['https']
  776.         (urltype, proxyhost) = splittype(proxy)
  777.         (proxyhost, proxyselector) = splithost(proxyhost)
  778.         i = proxyhost.find('@') + 1
  779.         proxyhost = proxyhost[i:]
  780.         (user, passwd) = self.get_user_passwd(proxyhost, realm, i)
  781.         if not user or passwd:
  782.             return None
  783.         
  784.         proxyhost = quote(user, safe = '') + ':' + quote(passwd, safe = '') + '@' + proxyhost
  785.         self.proxies['https'] = 'https://' + proxyhost + proxyselector
  786.         if data is None:
  787.             return self.open(newurl)
  788.         else:
  789.             return self.open(newurl, data)
  790.  
  791.     
  792.     def retry_http_basic_auth(self, url, realm, data = None):
  793.         (host, selector) = splithost(url)
  794.         i = host.find('@') + 1
  795.         host = host[i:]
  796.         (user, passwd) = self.get_user_passwd(host, realm, i)
  797.         if not user or passwd:
  798.             return None
  799.         
  800.         host = quote(user, safe = '') + ':' + quote(passwd, safe = '') + '@' + host
  801.         newurl = 'http://' + host + selector
  802.         if data is None:
  803.             return self.open(newurl)
  804.         else:
  805.             return self.open(newurl, data)
  806.  
  807.     
  808.     def retry_https_basic_auth(self, url, realm, data = None):
  809.         (host, selector) = splithost(url)
  810.         i = host.find('@') + 1
  811.         host = host[i:]
  812.         (user, passwd) = self.get_user_passwd(host, realm, i)
  813.         if not user or passwd:
  814.             return None
  815.         
  816.         host = quote(user, safe = '') + ':' + quote(passwd, safe = '') + '@' + host
  817.         newurl = 'https://' + host + selector
  818.         if data is None:
  819.             return self.open(newurl)
  820.         else:
  821.             return self.open(newurl, data)
  822.  
  823.     
  824.     def get_user_passwd(self, host, realm, clear_cache = 0):
  825.         key = realm + '@' + host.lower()
  826.         if key in self.auth_cache:
  827.             if clear_cache:
  828.                 del self.auth_cache[key]
  829.             else:
  830.                 return self.auth_cache[key]
  831.         
  832.         (user, passwd) = self.prompt_user_passwd(host, realm)
  833.         if user or passwd:
  834.             self.auth_cache[key] = (user, passwd)
  835.         
  836.         return (user, passwd)
  837.  
  838.     
  839.     def prompt_user_passwd(self, host, realm):
  840.         import getpass as getpass
  841.         
  842.         try:
  843.             user = raw_input('Enter username for %s at %s: ' % (realm, host))
  844.             passwd = getpass.getpass('Enter password for %s in %s at %s: ' % (user, realm, host))
  845.             return (user, passwd)
  846.         except KeyboardInterrupt:
  847.             print 
  848.             return (None, None)
  849.  
  850.  
  851.  
  852. _localhost = None
  853.  
  854. def localhost():
  855.     global _localhost
  856.     if _localhost is None:
  857.         _localhost = socket.gethostbyname('localhost')
  858.     
  859.     return _localhost
  860.  
  861. _thishost = None
  862.  
  863. def thishost():
  864.     global _thishost
  865.     if _thishost is None:
  866.         _thishost = socket.gethostbyname(socket.gethostname())
  867.     
  868.     return _thishost
  869.  
  870. _ftperrors = None
  871.  
  872. def ftperrors():
  873.     global _ftperrors
  874.     if _ftperrors is None:
  875.         import ftplib
  876.         _ftperrors = ftplib.all_errors
  877.     
  878.     return _ftperrors
  879.  
  880. _noheaders = None
  881.  
  882. def noheaders():
  883.     global _noheaders
  884.     if _noheaders is None:
  885.         import mimetools
  886.         
  887.         try:
  888.             StringIO = StringIO
  889.             import cStringIO
  890.         except ImportError:
  891.             StringIO = StringIO
  892.             import StringIO
  893.  
  894.         _noheaders = mimetools.Message(StringIO(), 0)
  895.         _noheaders.fp.close()
  896.     
  897.     return _noheaders
  898.  
  899.  
  900. class ftpwrapper:
  901.     
  902.     def __init__(self, user, passwd, host, port, dirs):
  903.         self.user = user
  904.         self.passwd = passwd
  905.         self.host = host
  906.         self.port = port
  907.         self.dirs = dirs
  908.         self.init()
  909.  
  910.     
  911.     def init(self):
  912.         import ftplib
  913.         self.busy = 0
  914.         self.ftp = ftplib.FTP()
  915.         self.ftp.connect(self.host, self.port)
  916.         self.ftp.login(self.user, self.passwd)
  917.         for dir in self.dirs:
  918.             self.ftp.cwd(dir)
  919.         
  920.  
  921.     
  922.     def retrfile(self, file, type):
  923.         import ftplib
  924.         self.endtransfer()
  925.         if type in ('d', 'D'):
  926.             cmd = 'TYPE A'
  927.             isdir = 1
  928.         else:
  929.             cmd = 'TYPE ' + type
  930.             isdir = 0
  931.         
  932.         try:
  933.             self.ftp.voidcmd(cmd)
  934.         except ftplib.all_errors:
  935.             self.init()
  936.             self.ftp.voidcmd(cmd)
  937.  
  938.         conn = None
  939.         if file and not isdir:
  940.             
  941.             try:
  942.                 cmd = 'RETR ' + file
  943.                 conn = self.ftp.ntransfercmd(cmd)
  944.             except ftplib.error_perm:
  945.                 reason = None
  946.                 if str(reason)[:3] != '550':
  947.                     raise IOError, ('ftp error', reason), sys.exc_info()[2]
  948.                 
  949.             except:
  950.                 str(reason)[:3] != '550'
  951.             
  952.  
  953.         None<EXCEPTION MATCH>ftplib.error_perm
  954.         if not conn:
  955.             self.ftp.voidcmd('TYPE A')
  956.             if file:
  957.                 cmd = 'LIST ' + file
  958.             else:
  959.                 cmd = 'LIST'
  960.             conn = self.ftp.ntransfercmd(cmd)
  961.         
  962.         self.busy = 1
  963.         return (addclosehook(conn[0].makefile('rb'), self.endtransfer), conn[1])
  964.  
  965.     
  966.     def endtransfer(self):
  967.         if not self.busy:
  968.             return None
  969.         
  970.         self.busy = 0
  971.         
  972.         try:
  973.             self.ftp.voidresp()
  974.         except ftperrors():
  975.             pass
  976.  
  977.  
  978.     
  979.     def close(self):
  980.         self.endtransfer()
  981.         
  982.         try:
  983.             self.ftp.close()
  984.         except ftperrors():
  985.             pass
  986.  
  987.  
  988.  
  989.  
  990. class addbase:
  991.     
  992.     def __init__(self, fp):
  993.         self.fp = fp
  994.         self.read = self.fp.read
  995.         self.readline = self.fp.readline
  996.         if hasattr(self.fp, 'readlines'):
  997.             self.readlines = self.fp.readlines
  998.         
  999.         if hasattr(self.fp, 'fileno'):
  1000.             self.fileno = self.fp.fileno
  1001.         else:
  1002.             
  1003.             self.fileno = lambda : pass
  1004.         if hasattr(self.fp, '__iter__'):
  1005.             self.__iter__ = self.fp.__iter__
  1006.             if hasattr(self.fp, 'next'):
  1007.                 self.next = self.fp.next
  1008.             
  1009.         
  1010.  
  1011.     
  1012.     def __repr__(self):
  1013.         return '<%s at %r whose fp = %r>' % (self.__class__.__name__, id(self), self.fp)
  1014.  
  1015.     
  1016.     def close(self):
  1017.         self.read = None
  1018.         self.readline = None
  1019.         self.readlines = None
  1020.         self.fileno = None
  1021.         if self.fp:
  1022.             self.fp.close()
  1023.         
  1024.         self.fp = None
  1025.  
  1026.  
  1027.  
  1028. class addclosehook(addbase):
  1029.     
  1030.     def __init__(self, fp, closehook, *hookargs):
  1031.         addbase.__init__(self, fp)
  1032.         self.closehook = closehook
  1033.         self.hookargs = hookargs
  1034.  
  1035.     
  1036.     def close(self):
  1037.         addbase.close(self)
  1038.         if self.closehook:
  1039.             self.closehook(*self.hookargs)
  1040.             self.closehook = None
  1041.             self.hookargs = None
  1042.         
  1043.  
  1044.  
  1045.  
  1046. class addinfo(addbase):
  1047.     
  1048.     def __init__(self, fp, headers):
  1049.         addbase.__init__(self, fp)
  1050.         self.headers = headers
  1051.  
  1052.     
  1053.     def info(self):
  1054.         return self.headers
  1055.  
  1056.  
  1057.  
  1058. class addinfourl(addbase):
  1059.     
  1060.     def __init__(self, fp, headers, url):
  1061.         addbase.__init__(self, fp)
  1062.         self.headers = headers
  1063.         self.url = url
  1064.  
  1065.     
  1066.     def info(self):
  1067.         return self.headers
  1068.  
  1069.     
  1070.     def geturl(self):
  1071.         return self.url
  1072.  
  1073.  
  1074.  
  1075. try:
  1076.     unicode
  1077. except NameError:
  1078.     
  1079.     def _is_unicode(x):
  1080.         return 0
  1081.  
  1082.  
  1083.  
  1084. def _is_unicode(x):
  1085.     return isinstance(x, unicode)
  1086.  
  1087.  
  1088. def toBytes(url):
  1089.     if _is_unicode(url):
  1090.         
  1091.         try:
  1092.             url = url.encode('ASCII')
  1093.         except UnicodeError:
  1094.             raise UnicodeError('URL ' + repr(url) + ' contains non-ASCII characters')
  1095.         except:
  1096.             None<EXCEPTION MATCH>UnicodeError
  1097.         
  1098.  
  1099.     None<EXCEPTION MATCH>UnicodeError
  1100.     return url
  1101.  
  1102.  
  1103. def unwrap(url):
  1104.     url = url.strip()
  1105.     if url[:1] == '<' and url[-1:] == '>':
  1106.         url = url[1:-1].strip()
  1107.     
  1108.     if url[:4] == 'URL:':
  1109.         url = url[4:].strip()
  1110.     
  1111.     return url
  1112.  
  1113. _typeprog = None
  1114.  
  1115. def splittype(url):
  1116.     global _typeprog
  1117.     if _typeprog is None:
  1118.         import re
  1119.         _typeprog = re.compile('^([^/:]+):')
  1120.     
  1121.     match = _typeprog.match(url)
  1122.     if match:
  1123.         scheme = match.group(1)
  1124.         return (scheme.lower(), url[len(scheme) + 1:])
  1125.     
  1126.     return (None, url)
  1127.  
  1128. _hostprog = None
  1129.  
  1130. def splithost(url):
  1131.     global _hostprog
  1132.     if _hostprog is None:
  1133.         import re
  1134.         _hostprog = re.compile('^//([^/?]*)(.*)$')
  1135.     
  1136.     match = _hostprog.match(url)
  1137.     if match:
  1138.         return match.group(1, 2)
  1139.     
  1140.     return (None, url)
  1141.  
  1142. _userprog = None
  1143.  
  1144. def splituser(host):
  1145.     global _userprog
  1146.     if _userprog is None:
  1147.         import re
  1148.         _userprog = re.compile('^(.*)@(.*)$')
  1149.     
  1150.     match = _userprog.match(host)
  1151.     if match:
  1152.         return map(unquote, match.group(1, 2))
  1153.     
  1154.     return (None, host)
  1155.  
  1156. _passwdprog = None
  1157.  
  1158. def splitpasswd(user):
  1159.     global _passwdprog
  1160.     if _passwdprog is None:
  1161.         import re
  1162.         _passwdprog = re.compile('^([^:]*):(.*)$')
  1163.     
  1164.     match = _passwdprog.match(user)
  1165.     if match:
  1166.         return match.group(1, 2)
  1167.     
  1168.     return (user, None)
  1169.  
  1170. _portprog = None
  1171.  
  1172. def splitport(host):
  1173.     global _portprog
  1174.     if _portprog is None:
  1175.         import re
  1176.         _portprog = re.compile('^(.*):([0-9]+)$')
  1177.     
  1178.     match = _portprog.match(host)
  1179.     if match:
  1180.         return match.group(1, 2)
  1181.     
  1182.     return (host, None)
  1183.  
  1184. _nportprog = None
  1185.  
  1186. def splitnport(host, defport = -1):
  1187.     global _nportprog
  1188.     if _nportprog is None:
  1189.         import re
  1190.         _nportprog = re.compile('^(.*):(.*)$')
  1191.     
  1192.     match = _nportprog.match(host)
  1193.     if match:
  1194.         (host, port) = match.group(1, 2)
  1195.         
  1196.         try:
  1197.             if not port:
  1198.                 raise ValueError, 'no digits'
  1199.             
  1200.             nport = int(port)
  1201.         except ValueError:
  1202.             nport = None
  1203.  
  1204.         return (host, nport)
  1205.     
  1206.     return (host, defport)
  1207.  
  1208. _queryprog = None
  1209.  
  1210. def splitquery(url):
  1211.     global _queryprog
  1212.     if _queryprog is None:
  1213.         import re
  1214.         _queryprog = re.compile('^(.*)\\?([^?]*)$')
  1215.     
  1216.     match = _queryprog.match(url)
  1217.     if match:
  1218.         return match.group(1, 2)
  1219.     
  1220.     return (url, None)
  1221.  
  1222. _tagprog = None
  1223.  
  1224. def splittag(url):
  1225.     global _tagprog
  1226.     if _tagprog is None:
  1227.         import re
  1228.         _tagprog = re.compile('^(.*)#([^#]*)$')
  1229.     
  1230.     match = _tagprog.match(url)
  1231.     if match:
  1232.         return match.group(1, 2)
  1233.     
  1234.     return (url, None)
  1235.  
  1236.  
  1237. def splitattr(url):
  1238.     words = url.split(';')
  1239.     return (words[0], words[1:])
  1240.  
  1241. _valueprog = None
  1242.  
  1243. def splitvalue(attr):
  1244.     global _valueprog
  1245.     if _valueprog is None:
  1246.         import re
  1247.         _valueprog = re.compile('^([^=]*)=(.*)$')
  1248.     
  1249.     match = _valueprog.match(attr)
  1250.     if match:
  1251.         return match.group(1, 2)
  1252.     
  1253.     return (attr, None)
  1254.  
  1255.  
  1256. def splitgophertype(selector):
  1257.     if selector[:1] == '/' and selector[1:2]:
  1258.         return (selector[1], selector[2:])
  1259.     
  1260.     return (None, selector)
  1261.  
  1262. _hextochr = dict((lambda .0: for i in .0:
  1263. ('%02x' % i, chr(i)))(range(256)))
  1264. _hextochr.update((lambda .0: for i in .0:
  1265. ('%02X' % i, chr(i)))(range(256)))
  1266.  
  1267. def unquote(s):
  1268.     res = s.split('%')
  1269.     for i in xrange(1, len(res)):
  1270.         item = res[i]
  1271.         
  1272.         try:
  1273.             res[i] = _hextochr[item[:2]] + item[2:]
  1274.         continue
  1275.         except KeyError:
  1276.             res[i] = '%' + item
  1277.             continue
  1278.             except UnicodeDecodeError:
  1279.                 res[i] = unichr(int(item[:2], 16)) + item[2:]
  1280.                 continue
  1281.             
  1282.         return ''.join(res)
  1283.  
  1284.  
  1285.  
  1286. def unquote_plus(s):
  1287.     s = s.replace('+', ' ')
  1288.     return unquote(s)
  1289.  
  1290. always_safe = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-'
  1291. _safemaps = { }
  1292.  
  1293. def quote(s, safe = '/'):
  1294.     cachekey = (safe, always_safe)
  1295.     
  1296.     try:
  1297.         safe_map = _safemaps[cachekey]
  1298.     except KeyError:
  1299.         safe += always_safe
  1300.         safe_map = { }
  1301.         for i in range(256):
  1302.             c = chr(i)
  1303.             if not c in safe or c:
  1304.                 pass
  1305.             safe_map[c] = '%%%02X' % i
  1306.         
  1307.         _safemaps[cachekey] = safe_map
  1308.  
  1309.     res = map(safe_map.__getitem__, s)
  1310.     return ''.join(res)
  1311.  
  1312.  
  1313. def quote_plus(s, safe = ''):
  1314.     if ' ' in s:
  1315.         s = quote(s, safe + ' ')
  1316.         return s.replace(' ', '+')
  1317.     
  1318.     return quote(s, safe)
  1319.  
  1320.  
  1321. def urlencode(query, doseq = 0):
  1322.     if hasattr(query, 'items'):
  1323.         query = query.items()
  1324.     else:
  1325.         
  1326.         try:
  1327.             if len(query) and not isinstance(query[0], tuple):
  1328.                 raise TypeError
  1329.         except TypeError:
  1330.             (ty, va, tb) = sys.exc_info()
  1331.             raise TypeError, 'not a valid non-string sequence or mapping object', tb
  1332.  
  1333.     l = []
  1334.     if not doseq:
  1335.         for k, v in query:
  1336.             k = quote_plus(str(k))
  1337.             v = quote_plus(str(v))
  1338.             l.append(k + '=' + v)
  1339.         
  1340.     else:
  1341.         for k, v in query:
  1342.             k = quote_plus(str(k))
  1343.             if isinstance(v, str):
  1344.                 v = quote_plus(v)
  1345.                 l.append(k + '=' + v)
  1346.                 continue
  1347.             if _is_unicode(v):
  1348.                 v = quote_plus(v.encode('ASCII', 'replace'))
  1349.                 l.append(k + '=' + v)
  1350.                 continue
  1351.             
  1352.             try:
  1353.                 x = len(v)
  1354.             except TypeError:
  1355.                 v = quote_plus(str(v))
  1356.                 l.append(k + '=' + v)
  1357.                 continue
  1358.  
  1359.             for elt in v:
  1360.                 l.append(k + '=' + quote_plus(str(elt)))
  1361.             
  1362.         
  1363.     return '&'.join(l)
  1364.  
  1365.  
  1366. def getproxies_environment():
  1367.     proxies = { }
  1368.     for name, value in os.environ.items():
  1369.         name = name.lower()
  1370.         if value and name[-6:] == '_proxy':
  1371.             proxies[name[:-6]] = value
  1372.             continue
  1373.     
  1374.     return proxies
  1375.  
  1376. if sys.platform == 'darwin':
  1377.     
  1378.     def getproxies_internetconfig():
  1379.         
  1380.         try:
  1381.             import ic as ic
  1382.         except ImportError:
  1383.             return { }
  1384.  
  1385.         
  1386.         try:
  1387.             config = ic.IC()
  1388.         except ic.error:
  1389.             return { }
  1390.  
  1391.         proxies = { }
  1392.         if 'UseHTTPProxy' in config and config['UseHTTPProxy']:
  1393.             
  1394.             try:
  1395.                 value = config['HTTPProxyHost']
  1396.             except ic.error:
  1397.                 pass
  1398.  
  1399.             proxies['http'] = 'http://%s' % value
  1400.         
  1401.         return proxies
  1402.  
  1403.     
  1404.     def proxy_bypass(x):
  1405.         return 0
  1406.  
  1407.     
  1408.     def getproxies():
  1409.         if not getproxies_environment():
  1410.             pass
  1411.         return getproxies_internetconfig()
  1412.  
  1413. elif os.name == 'nt':
  1414.     
  1415.     def getproxies_registry():
  1416.         proxies = { }
  1417.         
  1418.         try:
  1419.             import _winreg as _winreg
  1420.         except ImportError:
  1421.             return proxies
  1422.  
  1423.         
  1424.         try:
  1425.             internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, 'Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings')
  1426.             proxyEnable = _winreg.QueryValueEx(internetSettings, 'ProxyEnable')[0]
  1427.             if proxyEnable:
  1428.                 proxyServer = str(_winreg.QueryValueEx(internetSettings, 'ProxyServer')[0])
  1429.                 if '=' in proxyServer:
  1430.                     for p in proxyServer.split(';'):
  1431.                         (protocol, address) = p.split('=', 1)
  1432.                         import re
  1433.                         if not re.match('^([^/:]+)://', address):
  1434.                             address = '%s://%s' % (protocol, address)
  1435.                         
  1436.                         proxies[protocol] = address
  1437.                     
  1438.                 elif proxyServer[:5] == 'http:':
  1439.                     proxies['http'] = proxyServer
  1440.                 else:
  1441.                     proxies['http'] = 'http://%s' % proxyServer
  1442.                     proxies['ftp'] = 'ftp://%s' % proxyServer
  1443.             
  1444.             internetSettings.Close()
  1445.         except (WindowsError, ValueError, TypeError):
  1446.             pass
  1447.  
  1448.         return proxies
  1449.  
  1450.     
  1451.     def getproxies():
  1452.         if not getproxies_environment():
  1453.             pass
  1454.         return getproxies_registry()
  1455.  
  1456.     
  1457.     def proxy_bypass(host):
  1458.         
  1459.         try:
  1460.             import _winreg
  1461.             import re
  1462.         except ImportError:
  1463.             return 0
  1464.  
  1465.         
  1466.         try:
  1467.             internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, 'Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings')
  1468.             proxyEnable = _winreg.QueryValueEx(internetSettings, 'ProxyEnable')[0]
  1469.             proxyOverride = str(_winreg.QueryValueEx(internetSettings, 'ProxyOverride')[0])
  1470.         except WindowsError:
  1471.             return 0
  1472.  
  1473.         if not proxyEnable or not proxyOverride:
  1474.             return 0
  1475.         
  1476.         (rawHost, port) = splitport(host)
  1477.         host = [
  1478.             rawHost]
  1479.         
  1480.         try:
  1481.             addr = socket.gethostbyname(rawHost)
  1482.             if addr != rawHost:
  1483.                 host.append(addr)
  1484.         except socket.error:
  1485.             pass
  1486.  
  1487.         
  1488.         try:
  1489.             fqdn = socket.getfqdn(rawHost)
  1490.             if fqdn != rawHost:
  1491.                 host.append(fqdn)
  1492.         except socket.error:
  1493.             pass
  1494.  
  1495.         proxyOverride = proxyOverride.split(';')
  1496.         i = 0
  1497.         while i < len(proxyOverride):
  1498.             if proxyOverride[i] == '<local>':
  1499.                 proxyOverride[i:i + 1] = [
  1500.                     'localhost',
  1501.                     '127.0.0.1',
  1502.                     socket.gethostname(),
  1503.                     socket.gethostbyname(socket.gethostname())]
  1504.             
  1505.             i += 1
  1506.         for test in proxyOverride:
  1507.             test = test.replace('.', '\\.')
  1508.             test = test.replace('*', '.*')
  1509.             test = test.replace('?', '.')
  1510.             for val in host:
  1511.                 if re.match(test, val, re.I):
  1512.                     return 1
  1513.                     continue
  1514.             
  1515.         
  1516.         return 0
  1517.  
  1518. else:
  1519.     getproxies = getproxies_environment
  1520.     
  1521.     def proxy_bypass(host):
  1522.         return 0
  1523.  
  1524.  
  1525. def test1():
  1526.     s = ''
  1527.     for i in range(256):
  1528.         s = s + chr(i)
  1529.     
  1530.     s = s * 4
  1531.     t0 = time.time()
  1532.     qs = quote(s)
  1533.     uqs = unquote(qs)
  1534.     t1 = time.time()
  1535.     if uqs != s:
  1536.         print 'Wrong!'
  1537.     
  1538.     print repr(s)
  1539.     print repr(qs)
  1540.     print repr(uqs)
  1541.     print round(t1 - t0, 3), 'sec'
  1542.  
  1543.  
  1544. def reporthook(blocknum, blocksize, totalsize):
  1545.     print 'Block number: %d, Block size: %d, Total size: %d' % (blocknum, blocksize, totalsize)
  1546.  
  1547.  
  1548. def test(args = []):
  1549.     if not args:
  1550.         args = [
  1551.             '/etc/passwd',
  1552.             'file:/etc/passwd',
  1553.             'file://localhost/etc/passwd',
  1554.             'ftp://ftp.gnu.org/pub/README',
  1555.             'http://www.python.org/index.html']
  1556.         if hasattr(URLopener, 'open_https'):
  1557.             args.append('https://synergy.as.cmu.edu/~geek/')
  1558.         
  1559.     
  1560.     
  1561.     try:
  1562.         for url in args:
  1563.             print '----------', url, '----------'
  1564.             (fn, h) = urlretrieve(url, None, reporthook)
  1565.             print fn
  1566.             if h:
  1567.                 print '======'
  1568.                 for k in h.keys():
  1569.                     print k + ':', h[k]
  1570.                 
  1571.                 print '======'
  1572.             
  1573.             fp = open(fn, 'rb')
  1574.             data = fp.read()
  1575.             del fp
  1576.             if '\r' in data:
  1577.                 table = string.maketrans('', '')
  1578.                 data = data.translate(table, '\r')
  1579.             
  1580.             print data
  1581.             (fn, h) = (None, None)
  1582.         
  1583.         print '-' * 40
  1584.     finally:
  1585.         urlcleanup()
  1586.  
  1587.  
  1588.  
  1589. def main():
  1590.     import getopt as getopt
  1591.     import sys
  1592.     
  1593.     try:
  1594.         (opts, args) = getopt.getopt(sys.argv[1:], 'th')
  1595.     except getopt.error:
  1596.         msg = None
  1597.         print msg
  1598.         print 'Use -h for help'
  1599.         return None
  1600.  
  1601.     t = 0
  1602.     for o, a in opts:
  1603.         if o == '-t':
  1604.             t = t + 1
  1605.         
  1606.         if o == '-h':
  1607.             print 'Usage: python urllib.py [-t] [url ...]'
  1608.             print '-t runs self-test;', 'otherwise, contents of urls are printed'
  1609.             return None
  1610.             continue
  1611.     
  1612.     if t:
  1613.         if t > 1:
  1614.             test1()
  1615.         
  1616.         test(args)
  1617.     elif not args:
  1618.         print 'Use -h for help'
  1619.     
  1620.     for url in args:
  1621.         print urlopen(url).read(),
  1622.     
  1623.  
  1624. if __name__ == '__main__':
  1625.     main()
  1626.  
  1627.